package com.learn.concurrent;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Time;
import java.util.concurrent.*;

/**
 * @author wangxing
 * @version 2020/9/2 21:14 Administrator
 */
public class LearnThreadPoolExecutor {
    public static final int corePoolSize=5;
    public static final int maximumPoolSize=10;
    private static final int capacity=10;
    public static final Logger logger = LoggerFactory.getLogger(LearnThreadPoolExecutor.class);
    public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 10, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(capacity));

    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
//        submitThread_WaitResult();
        runThreadPoolUseNoCoreThread();
//        runThreadPoolUseWaitQueue();
//        submitThread_WaitResult_TimeOut();
        threadPoolExecutor.shutdown();
    }

    /**
     * 超出核心线程数的线程会优先进入等待队列
     */
    public static void runThreadPoolUseWaitQueue(){
        for(int i=0;i<corePoolSize+1;i++){
            int finalI = i;
            threadPoolExecutor.execute(()->{
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("线程进入队列执行{}", finalI);
            });
        }
    }
    /**
     * 超出核心线程并且超出阻塞队列数量后开始创建非核心线程
     */
    public static void runThreadPoolUseNoCoreThread(){
        for(int i=0;i<corePoolSize+capacity+5;i++){
            int finalI = i;
            threadPoolExecutor.execute(()->{
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                logger.info("线程进入队列执行{}", finalI);
            });
        }
    }
    /**
     * 使用submit可以等待线程执行完后获取线程的执行结果,获取结果调用get时是阻塞的
     */
    public static void submitThread_WaitResult() {
        Future<String> submit = threadPoolExecutor.submit(() -> {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("22222");
            return "33333";
        });
        System.out.println("11111");
        try {
            System.out.println(submit.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("44444");
    }

    /**
     * 使用submit可以等待线程执行完后获取线程的执行结果,获取结果调用get时是阻塞的,get可以设置超时时间,到达超时时间还未完成任务,则抛出异常
     */
    public static void submitThread_WaitResult_TimeOut() {
        Future<String> submit = threadPoolExecutor.submit(() -> {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("22222");
            return "33333";
        });
        System.out.println("11111");
        try {
            System.out.println(submit.get(1, TimeUnit.SECONDS));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            threadPoolExecutor.shutdown();
        }
        System.out.println("44444");
    }
}
